<template>
  <el-dialog
    title="图片内容识别"
    :visible.sync="visible"
    width="600px"
    :close-on-click-modal="false"
    :destroy-on-close="true"
    @closed="handleDialogClosed"
    custom-class="recognition-dialog">
    
    <div class="upload-container">
      <el-upload
        class="uploader"
        action="#"
        accept=".jpg,.jpeg,.png,.gif,.bmp"
        :auto-upload="false"
        :show-file-list="false"
        :on-change="handleFileChange"
        :before-upload="beforeUpload"
        >
        <div class="upload-area" :class="{'is-disabled': processing || processingWithSummary}">
          <template v-if="!fileUrl">
            <i class="el-icon-plus upload-icon"></i>
            <div class="upload-text">点击上传图片</div>
            <div class="upload-tip">支持 JPG、PNG、GIF、BMP 格式的图片</div>
          </template>
          <template v-else>
            <img v-if="isImage" :src="fileUrl" class="preview-image">
          </template>
        </div>
      </el-upload>
      
      <div class="recognize-btn-container">
        <el-button 
          type="primary" 
          class="recognize-btn"
          size="small"
          :disabled="!fileUrl || processing || processingWithSummary"
          @click="handleProcess">
          {{ processing ? '识别中...' : '开始识别' }}
        </el-button>
        
        <el-button 
          type="success" 
          class="recognize-btn"
          size="small"
          :disabled="!fileUrl || processing || processingWithSummary"
          @click="handleProcessAndSummarize">
          {{ processingWithSummary ? '识别中...' : '识别并总结' }}
        </el-button>
      </div>
    </div>

    <div class="result-container">
      <div v-if="processing || processingWithSummary" class="custom-loading-container">
        <div class="custom-loading-spinner"></div>
        <div class="custom-loading-text">正在识别中...</div>
      </div>
      <template v-else>
        <div v-if="!result.description && !result.summary" class="empty-result">
          <i class="el-icon-warning-outline"></i>
          <span>暂无识别结果</span>
        </div>
        <div v-else class="recognition-result">
          <template v-if="result.description">
            <div class="result-title">识别结果：</div>
            <div class="result-content">{{ result.description }}</div>
          </template>
          <template v-if="result.summary">
            <div class="result-title">总结内容：</div>
            <div class="result-content">{{ result.summary }}</div>
          </template>
        </div>
      </template>
    </div>
  </el-dialog>
</template>

<script>
export default {
  name: 'ImageRecognitionDialog',
  props: {
    visible: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      processing: false,
      processingWithSummary: false,
      fileUrl: '',
      file: null,
      result: {
        description: '',
        summary: ''
      },
      isImage: true,
    }
  },
  methods: {
    getInitialState() {
      return {
        processing: false,
        processingWithSummary: false,
        fileUrl: '',
        file: null,
        result: {
          description: '',
          summary: ''
        },
        isImage: true,
      }
    },
    beforeUpload(file) {
      // 验证文件类型
      const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/bmp']
      if (!allowedTypes.includes(file.type)) {
        this.$message.error('请上传 JPG、PNG、GIF、BMP 格式的图片')
        return false
      }
      
      // 验证文件大小（限制为10MB）
      const isLt10M = file.size / 1024 / 1024 < 10
      if (!isLt10M) {
        this.$message.error('图片大小不能超过 10MB')
        return false
      }
      return false // 阻止自动上传
    },
    
    handleFileChange(file) {
      this.file = file.raw
      this.isImage = file.raw.type.startsWith('image/')
      this.fileUrl = URL.createObjectURL(file.raw)
    },
    
    async handleProcess() {
      if (!this.file) {
        this.$message.warning('请先上传图片')
        return
      }
      
      this.processing = true
      try {
        const formData = new FormData()
        formData.append('image', this.file)
        
        const response = await this.$axios.post('/api/recognize_image/', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          },
          timeout: 60000
        })
        
        if (response.data.code === 200) {
          this.result = {
            description: response.data.data.description,
            summary: ''
          }
          this.$message.success('识别成功')
        } else {
          this.$message.error(response.data.msg || '识别失败')
        }
      } catch (error) {
        console.error('识别失败:', error)
        if (error.code === 'ECONNABORTED') {
          this.$message.error('请求超时，请检查网络连接或后端服务负载')
        } else if (error.message.includes('Network Error')) {
          this.$message.error('网络错误，请确认后端服务是否已启动')
        } else if (error.response) {
          const status = error.response.status
          if (status === 504) {
            this.$message.error('服务器处理超时，请稍后重试或联系管理员')
          } else {
            this.$message.error(error.response.data.msg || `识别失败(${status})，请重试`)
          }
        } else {
          this.$message.error('识别失败，请重试')
        }
      } finally {
        this.processing = false
      }
    },
    
    async handleProcessAndSummarize() {
      if (!this.file) {
        this.$message.warning('请先上传图片')
        return
      }
      
      this.processingWithSummary = true
      try {
        const formData = new FormData()
        formData.append('image', this.file)
        formData.append('need_summary', 'true')
        
        const response = await this.$axios.post('/api/recognize_image/', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          },
          timeout: 90000
        })
        
        if (response.data.code === 200) {
          this.result = {
            description: response.data.data.description,
            summary: response.data.data.summary
          }
          this.$message.success('识别并总结成功')
        } else {
          this.$message.error(response.data.msg || '识别并总结失败')
        }
      } catch (error) {
        console.error('识别并总结失败:', error)
        if (error.code === 'ECONNABORTED') {
          this.$message.error('请求超时，请检查网络连接或后端服务负载')
        } else if (error.message.includes('Network Error')) {
          this.$message.error('网络错误，请确认后端服务是否已启动')
        } else if (error.response) {
          const status = error.response.status
          if (status === 504) {
            this.$message.error('服务器处理超时，请稍后重试或联系管理员')
          } else {
            this.$message.error(error.response.data.msg || `识别并总结失败(${status})，请重试`)
          }
        } else {
          this.$message.error('识别并总结失败，请重试')
        }
      } finally {
        this.processingWithSummary = false
      }
    },
    
    reset() {
      if (this.fileUrl) {
        URL.revokeObjectURL(this.fileUrl)
      }
      this.fileUrl = ''
      this.file = null
      this.result = {
        description: '',
        summary: ''
      }
      this.processing = false
      this.processingWithSummary = false
    },
    
    handleDialogClosed() {
      // 清理文件资源
      if (this.fileUrl) {
        URL.revokeObjectURL(this.fileUrl)
      }
      
      // 重置所有状态到初始值
      const initialState = this.getInitialState()
      Object.keys(initialState).forEach(key => {
        this[key] = initialState[key]
      })
      
      // 触发父组件更新，避免直接修改props
      this.$emit('update:visible', false)
    }
  },
  beforeDestroy() {
    // 组件销毁前清理资源
    if (this.fileUrl) {
      URL.revokeObjectURL(this.fileUrl)
    }
  }
}
</script>

<style scoped>
.recognition-dialog {
  border-radius: 8px;
  
  :deep(.el-dialog__body) {
    padding: 20px;
  }
  
  :deep(.el-dialog__header) {
    padding: 15px 20px;
    border-bottom: 1px solid #e4e7ed;
    margin-right: 0;
  }
  
  :deep(.el-dialog__headerbtn) {
    top: 15px;
  }
}

.upload-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin-bottom: 20px;
}

.uploader {
  width: 100%;
  display: flex;
  justify-content: center;
}

.upload-area {
  width: 360px;
  height: 200px;
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  transition: all 0.3s;
  background-color: #fff;

  &:hover {
    border-color: #409EFF;
    
    .upload-icon {
      color: #409EFF;
    }
    
    .upload-text {
      color: #409EFF;
    }
  }

  &.is-disabled {
    cursor: not-allowed;
    opacity: 0.6;
    pointer-events: none;
  }
}

.upload-icon {
  font-size: 28px;
  color: #8c939d;
  margin-bottom: 8px;
  transition: all 0.3s;
}

.upload-text {
  font-size: 14px;
  color: #606266;
  margin-bottom: 4px;
  transition: color 0.3s;
}

.upload-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.recognize-btn-container {
  display: flex;
  justify-content: space-between;
  margin-top: 16px;
  width: 180px;
}

.recognize-btn {
  width: 48%;
}

.result-container {
  min-height: 120px;
  max-height: 300px;
  padding: 16px;
  background-color: #f5f7fa;
  border-radius: 4px;
  position: relative;
  overflow-y: auto;
  margin-top: 20px;
}

.custom-loading-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 120px;
  padding: 20px;
}

.custom-loading-spinner {
  width: 50px;
  height: 50px;
  background: url('../assets/loading.png') no-repeat center center;
  background-size: contain;
  animation: rotate 1.5s linear infinite;
}

.custom-loading-text {
  margin-top: 10px;
  color: #606266;
  font-size: 14px;
}

.empty-result {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #909399;
  min-height: 120px;
}

.empty-result i {
  font-size: 24px;
  margin-bottom: 8px;
}

.recognition-result {
  padding: 8px;
  overflow-wrap: break-word;
}

.result-title {
  font-weight: bold;
  margin-bottom: 8px;
  color: #303133;
}

.result-content {
  line-height: 1.6;
  color: #606266;
  white-space: pre-wrap;
  word-break: break-all;
  max-width: 100%;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style> 